import { TScrollArea } from 't/basic/scroll-area'
import TChip from 't/basic/chip/Component.vue'
import { useI18n } from 'vue-i18n';
import dayjs from 'dayjs';

import useMappingProps from 't/common/hooks/useMappingProps';
import {
  commonProps,
  pickOwnForBasicComponent,
  usePropsTwoWayValues,
  // zipFasDynamicFilter,
  filter2FasDynamicFilter,
  valueDestructuring,
  valueStructuring,
  isValueDestructuring,
  SymbolDestructuring,
} from 't/common/utils';
import {
  computed,
  defineComponent,
  getCurrentInstance,
  nextTick,
  onMounted,
  reactive,
  ref,
  toRef,
  watch,
} from 'vue';

import './index.scss';
import _, { forIn, transform, zipObject } from 'lodash';

import Desktop from './components/Desktop';
import Mobile from './components/Mobile';

import { date, debounce, dom, setCssVar, useQuasar, scroll } from '@teld/q-components';

import {
  dateFilterObj,
  FilterFieldValueRange,
  FilterFieldDisplayType,
  getDateRange2Value,
  setHelpTipBase,
} from 't/bussiness/quick-filter/use-quick-filter';
import { console } from 't/third-party/vuedraggable/util/console';
import tree from 't/basic/tree';
import label from 't/basic/label';

export default defineComponent({
  name: 'TQuickFilter',
  directives: {
    removeTabindex: {
      mounted(el) {
        // 移除 tabindex 属性
        el?.removeAttribute('tabindex');
      },
    },
  },
  props: {
    ...commonProps,
    loading: {
      type: Boolean,
      default() {
        return false;
      },
    },
    filterFields: { type: Array, default: () => [] },
    /** 运行时绑定属性 */
    quickItems: {
      type: Object,
      default: () => {
        return {};
      },
    },
    quickItemSummary: {
      type: Object,
      default() {
        return {};
      },
    },
    isPcOnly: {
      type: Boolean,
      default() {
        return false;
      },
    },
    displayMode: {
      type: String,
      default() {
        return 'reactive';
      },
    },
    optColumns: {
      type: [Array, String, Object],
      default() {
        return [];
      },
    },
    showTotalCount: { type: Boolean, default: false },
    showSummaryCount: { type: Boolean, default: true },
    selectHelperSearchConfig: {
      type: Object,
      default() {
        return {};
      },
    },
    displayFields: {
      //** 当可见列设置为null标识不显示内容项 */
      type: Array,
      default() {
        return [];
      },
    },
    initQuerySummary: {
      type: Boolean,
      default() {
        return true;
      },
    },
    optionsPosition: {
      type: String,
      default: 'bottom',
    },
  },
  emits: [
    'init',
    'quickItemsChanged',
    'filterChanged',
    'querySummary',
    'searchValue',
    'loadMore',
  ],
  setup(props, { attrs, emit, expose, slots }) {
    const vm = getCurrentInstance();
    const $q = useQuasar();
    const { t } = useI18n({ useScope: 'global' });
    const inDesign = ref(!!window['fas']?.inDesign);

    const refRoot = ref(HTMLElement);

    const { ...twoWayProps } = usePropsTwoWayValues([]);

    const valueRangeWithPrecast = filterFieldConf => {
      switch (filterFieldConf.valueType) {
        case FilterFieldValueRange.Boolean:
          return [
            {
              selected: false,
              label: $q.lang.quickFilter?.TRUE || '是',
              value: true,
            },
            {
              selected: false,
              label: $q.lang.quickFilter?.FALSE || '否',
              value: false,
            },
          ];
        case FilterFieldValueRange.Date:
          return [{ selected: false, label: '', value: '' }];
        case FilterFieldValueRange.SDO:
          if (
            FilterFieldDisplayType.SelectHelper === filterFieldConf.displayType
          ) {
            return (
              cacheSelectHelperValue(filterFieldConf.ID) || [{ selected: false }]
            );
          }
          break;
      }
    };

    const setValueRangeSelected = (filterFieldConf, valueRange) => {
      forIn(valueRange, valueRangeItem => {
        let code = `${filterFieldConf.tableAlias || filterFieldConf.tableCode}.${filterFieldConf.fieldCode}.${valueRangeItem.value}`;
        switch (filterFieldConf.valueType) {
          case FilterFieldValueRange.Date:
            code = `${filterFieldConf.tableAlias || filterFieldConf.tableCode}.${filterFieldConf.fieldCode}`;
            valueRangeItem.value = quickFilterSnapshoot[code]?.value || '';
            break;
        }

        let selected = quickFilterSnapshoot[code]?.selected || false;
        valueRangeItem.selected = selected;

        if (filterFieldConf.hideEmpty && valueRangeItem.count < 1) {
          valueRangeItem.selected = false;
        }
      });
      return valueRange;
    };

    const computedQuickItemSummary = computed(() => {
      return publicMethod.wrapSummary(props.quickItemSummary);
    });

    const valueRangeWithSummary = filterFieldConf => {
      if (
        inDesign.value &&
        FilterFieldValueRange.SDO == filterFieldConf.valueType
      ) {
        let enableStatistics = filterFieldConf.enableStatistics;
        if ('custom' == filterFieldConf.mockDataModel) {
          return _.map(filterFieldConf.customMockData, (item, index) => {
            return {
              label: `${item.label}`,
              value: item.label,
              count: index * 10,
            };
          });
        } else {
          return [
            {
              label: `模拟项1`,
              value: 'mock1',
              count: 100,
            },
            {
              label: `模拟项2`,
              value: 'mock2',
              count: 0,
            },
            {
              label: `模拟项3`,
              value: 'mock3',
              count: 50,
            },
          ];
        }
      }

      let summary = computedQuickItemSummary.value[filterFieldConf.fieldAlias];
      return props.quickItems[filterFieldConf.fieldAlias]?.map(
        (quickItem, index) => {
          let selected = false;
          let returnValue = { selected: selected, ...quickItem };
          if (filterFieldConf.enableStatistics) {
            if (summary && summary[quickItem.value]) {
              returnValue.count = summary[quickItem.value];
            } else {
              returnValue.count = 0;
            }
          }
          return returnValue;
        },
      );
    };

    const computedFilterFields = computed(() => {
      return clearFlag.value
        ? mappingProps.filterFields
        : mappingProps.filterFields;
    });

    const computedFilterItems = computed(() => {
      let returnValue = computedFilterFields.value.map(item => {
        let valueRange = valueRangeWithSummary(item);
        if (!valueRange) {
          valueRange = valueRangeWithPrecast(item);
        }
        valueRange = setValueRangeSelected(item, valueRange);

        let fieldName = item.fieldName;

        let column = _.find(props.optColumns, c => {
          return (
            (c.fieldAlias || c.dataField) ==
            (item.displayFieldAlias || item.fieldAlias)
          );
        });
        if (column) {
          fieldName = column.fieldName || column.caption || fieldName;
          if (column.RefSchemaExpr) {
            fieldName = t(`${column.RefSchemaExpr}.Text`, fieldName);
          }
          if (
            column.ValueInfo_caption &&
            column.ValueInfo_caption.ReferenceExpr
          ) {
            fieldName = t(
              column.ValueInfo_caption.ReferenceExpr,
              column.caption || fieldName,
            );
          }
        }
        return { ...item, fieldName, valueRange };
      });

      return reactive(returnValue);
    });

    const computedDisplayFilterItems = computed(() => {
      if (null === props.displayFields) {
        //** 当可见列设置为null标识不显示内容项 */
        return [];
      }
      if (props.displayFields.length > 0) {
        return computedFilterItems.value.filter(f => {
          return props.displayFields.includes(f.fieldCode);
        });
      } else {
        return computedFilterItems.value;
      }
    });

    let clearFlag = ref(false);
    let quickFilterSnapshoot = {};
    const computedFilterStatement = computed(() => {
      const SKIP_ELEMENT_TYPE = '[SKIP]';
      let filters = computedFilterItems.value?.map(item => {
        let code = `${item.tableAlias || item.tableCode}.${item.fieldCode}`;
        let itemValue = item.valueRange?.filter(val => {
          let quickFilterSnapshoot_Key = `${code}.${val.value}`;
          switch (item.valueType) {
            case FilterFieldValueRange.Date:
              quickFilterSnapshoot_Key = code;
              break;
          }

          quickFilterSnapshoot[quickFilterSnapshoot_Key] = {
            selected: val?.selected,
            value: val?.value,
          };

          return val?.selected;
        });
        if (
          itemValue?.length === 0 &&
          (item.valueType === FilterFieldValueRange.SDO ||
            item.valueType === FilterFieldValueRange.Boolean)
        ) {
          return { ElementType: SKIP_ELEMENT_TYPE };
        }
        let value = itemValue?.map(mapItem => {
          return mapItem.value;
        });
        // console.log('item.dataType;', item.dataType);
        let filterValue = {
          ElementType: 'Filter',
          Code: code,
          // Condition: 'in',
          Condition: item.isMultiple ? 'in' : '=',
          ValueType: 0,
          Name: item.fieldName,
          DataType: item.dataType || '',
          // Value: item.isMultiple ? value : _.first(value),
          // .reduce((a,v)=>{return a+=`${v===''?'\'\'':v},`},"").replace(/\,{1,}$/g,'')
          Value: value?.reduce((prev, next, index, a) => {
            let val = next;
            /** 转换字符串， 对于null 处理为 null， 空字符 处理为 "''" */
            if (item.isMultiple && value.length > 1) {
              switch (next) {
                // case '':
                //   val = `''`;
                //   break;
                case null:
                  val = 'null';
                  break;
                default:
                  val = next;
                  break;
              }
              if (index < value.length - 1) {
                val += ',';
              }
            } else {
              return val;
            }
            return prev + val;
            // return (prev += `${next === '' ? "''" : next},`);
          }, ''),
          // .replace(/\,{1,}$/g, ''),
          // Value: value?.join(),
          ValueName: itemValue
            ?.map(mapItem => {
              return mapItem.label;
            })
            ?.join(),
        };
        switch (item.valueType) {
          case FilterFieldValueRange.Date:
            let valueName = item.valueRange[0].value || '';
            filterValue.Condition = 'between';
            filterValue.Value = dateFilterObj[valueName].getDateFilter();

            filterValue.ValueName =
              $q.lang?.quickFilter?.dateFilterOpts?.[
                valueName.replace('@', '')
              ];
            // filterValue.DataType = item.dataType;
            filterValue.DataType = 'DateTime';
            break;
          case FilterFieldValueRange.Boolean:
            filterValue.DataType = 'Boolean';
            if (true === filterValue.Value || false === filterValue.Value) {
              filterValue.Value = `${filterValue.Value}`;
            }
            break;
        }
        return filterValue;
      });

      filters = filters.filter(f => {
        if (f.ElementType === SKIP_ELEMENT_TYPE) {
          return false;
        }
        return (
          null === f.Value ||
          '' === f.Value ||
          (undefined !== f.Value && `${f.Value}`?.length > 0)
        );
      });

      if (filters.length == 0) {
        return {};
      } else {
        return {
          ElementType: 'Group',
          Filters: filters
            .map((item, index) => {
              return [
                item,
                index < filters.length - 1
                  ? { ElementType: 'Relation', Relation: 'and' }
                  : null,
              ].filter(Boolean);
            })
            .flat(Infinity),
        };
      }
    });

    const emitFilterChanged = debounce(function (emitArgs = {}) {
      emit('filterChanged', emitArgs);
      // emitQuerySummary(); /** 这里不需要触发统计查询，因为统计查询不受本来条件的影响 */
    }, 200);

    const emitSearchValue = debounce(function (val) {
      emit('searchValue', val);
    }, 200);

    const emitQuerySummary = function () {
      let summaryGroupColumnStatement = publicMethod.getGroupColumnStatement();

      if (summaryGroupColumnStatement?.ExtSetting?.GroupColumns?.length > 0) {
        emit('querySummary', {
          summaryGroupColumnStatement,
        });
      }
    };

    const computedGroupColumnStatement = computed(() => {
      let groupColumns = computedFilterItems.value
        ?.filter(f => f.enableStatistics)
        ?.map(item => {
          return {
            Code: `${item.tableAlias || item.tableCode}.${item.fieldCode}`,
          };
        });

      return groupColumns.length > 0
        ? {
            ExtSetting: {
              GroupColumns: groupColumns,
            },
          }
        : {};
    });

    function filterSDOItems(filterItems) {
      return filterItems?.filter(f => FilterFieldValueRange.SDO == f.valueType);
    }

    const computedSDOFilterItems = computed(() => {
      return filterSDOItems(computedFilterFields.value);
      // return computedFilterFields.value?.filter(
      //   f => FilterFieldValueRange.SDO == f.valueType,
      // );
    });
    function filterSelectHelperItems(filterItems) {
      return filterItems?.filter(
        f => FilterFieldDisplayType.SelectHelper == f.displayType,
      );
    }
    const computedSelectHelperItems = computed(() => {
      return filterSelectHelperItems(computedFilterFields.value);
    });

    const publicMethod = {
      setFilters(filters) {
        return publicMethod.stringifyQuickFilter(filters);
      },
      getFilters(filters) {
        return publicMethod.stringifyQuickFilter(filters);
      },
      statisticalQuery() {
        publicMethod.querySummary();
      },
      stringifyQuickFilter(advancedFilter) {
        let filter = publicMethod.getQuickFilter(advancedFilter);
        return filter == null ? null : JSON.stringify(filter);
      },
      getQuickFilter: advancedFilter => {
        let { Filters, ...quickFilter } = JSON.parse(
          JSON.stringify(publicMethod.getQuickFilterStatement()),
        );

        if (advancedFilter) {
          if (typeof advancedFilter === 'string') {
            try {
              advancedFilter = JSON.parse(advancedFilter);
            } catch (error) {
              console.warn('QuickFilter.getQuickFilter', error);
            }
          }
          if (false === quickFilter.hasOwnProperty('ElementType')) {
            /** 当 传入了 过滤条件 但是快速过滤本身没有条件时，直接返回传入的条件 */
            return advancedFilter;
          }

          if (advancedFilter.Filters && advancedFilter.Filters.length > 0) {
            if (Filters) {
              Filters?.push({
                ElementType: 'Relation',
                Relation: 'and',
              });
              Filters?.push(advancedFilter);
            } else {
              Filters = advancedFilter.Filters;
            }
          }
        }
        let returnValue = { ...quickFilter, Filters };
        return returnValue.hasOwnProperty('ElementType') ? returnValue : null;
        // return Filters?.length > 0 ? { ...quickFilter, Filters } : null;
      },
      mergeAdvancedFilter: advancedFilter => {
        return advancedFilter;
      },
      mockSummary() {
        let summary = Math.floor(Math.random() * 100);
        if (summary < 10) {
          summary = 0;
        }
        return summary;
      },
      filterItemsIsSDO: computedSDOFilterItems,
      filterSDOItems,
      filterStatement: computedFilterStatement,
      getFilterStatement: () => {
        return computedFilterStatement.value;
      },
      groupColumnStatement: computedGroupColumnStatement,
      getGroupColumnStatement: () => {
        return computedGroupColumnStatement.value;
      },
      getQuickFilterStatement: () => {
        return {
          ...publicMethod.getFilterStatement(),
        };
      },
      getSummaryFilterExpression: () => {
        return {
          ...publicMethod.getFilterStatement(),
          ...publicMethod.getGroupColumnStatement(),
        };
      },
      getGroupByFilter(advancedFilter) {
        let outerAdvancedFilter = { ElementType: 'Group', Filters: [] };
        if (advancedFilter) {
          if (typeof advancedFilter === 'string') {
            try {
              advancedFilter = JSON.parse(advancedFilter);
            } catch (error) {
              console.warn('QuickFilter.getQuickFilter', error);
            }
          }
          outerAdvancedFilter = advancedFilter;
        }
        return JSON.stringify({
          ...outerAdvancedFilter,
          ...publicMethod.getGroupColumnStatement(),
        });
      },
      wrapSummary: (quickItemSummaryRaw, Cnt = 'Total') => {
        // [
        //   { Total: mockSummary(), State: "隐藏", State2: "隐藏" },
        //   { Total: mockSummary(), State: "隐藏", State2: "隐藏" },
        //   { Total: mockSummary(), State: "CN", State2: "CN" },
        //   { Total: mockSummary(), State: "CN", State2: "CN" },
        //   { Total: mockSummary(), State: "EN", State2: "EN" },
        //   { Total: mockSummary(), State: "EN", State2: "EN" },
        // ]

        let keys = _.keys(_.first(quickItemSummaryRaw));
        _.remove(keys, k => k == Cnt);

        let returnValue = _.transform(
          keys,
          (rSummary, propKey) => {
            let groupByPropKey = _.groupBy(quickItemSummaryRaw, propKey);
            rSummary[propKey] = _.transform(
              groupByPropKey,
              (summary, sumValue, summaryKey) => {
                summary[summaryKey] = _.sumBy(sumValue, Cnt);
              },
              {},
            );
          },
          {},
        );

        return returnValue;

        // _.transform(_.groupBy(f,'State'),(r,v,k)=>{r[k]=_.sumBy(v,'Cnt')})

        // transform(quickItemSummaryRaw, (r, val), {});
      },
      getQuickFilterSnapshoot() {
        return quickFilterSnapshoot;
      },
      clearSelectedWithSelectHelper() {
        const clearObj = _.transform(
          computedSelectHelperItems.value,
          (r, item) => {
            r[item.fieldAlias] = null;
            cacheSelectHelperValue(item.ID, []);
            return r;
          },
          {},
        );
        publicMethod.setSelectedItem(clearObj);
      },
      clearSelected() {
        clearFlag.value = !clearFlag.value;
        forIn(quickFilterSnapshoot, (value, key) => {
          value.selected = false;
          value.value = '';
        });
        publicMethod.clearSelectedWithSelectHelper();
      },
      query() {
        emitFilterChanged();
      },
      querySummary() {
        emitQuerySummary();
      },
      symbolDestructuring: SymbolDestructuring,
      getSelectedValue({ filters, destructuring = true } = {}) {
        let qf = publicMethod.getQuickFilter(filters);
        if (qf && qf.Filters) {
          let returnValue = publicMethod._getSelectedValue(
            {},
            qf.Filters,
            destructuring,
          );
          return returnValue || {};
        } else {
          return {};
        }
      },
      _getSelectedValue(o, Filters, destructuring = true) {
        let fasDynamicFilter = filter2FasDynamicFilter(
          o,
          Filters,
          destructuring,
        );
        let mapKey = _.keyBy(
          props.filterFields,
          f => `${f.tableAlias || f.tableCode}.${f.fieldCode}`,
        );
        let returnValue = _.transform(
          fasDynamicFilter,
          (r, val, key) => {
            const field = mapKey[key];
            if (field) {
              r[field.fieldAlias] = val;
            } else {
              r[_.last(key.split('.'))] = val;
            }
          },
          {},
        );
        return returnValue;
      },

      getFasDynamicFilter(filters) {
        let qf = publicMethod.getQuickFilter(filters);
        if (qf && qf.Filters) {
          let returnValue = publicMethod.zipFasDynamicFilter({}, qf.Filters);
          return returnValue || {};
        } else {
          return {};
        }
      },
      zipFasDynamicFilter(o, Filters) {
        let fasDynamicFilter = filter2FasDynamicFilter(o, Filters);
        let mapKey = _.keyBy(
          props.filterFields,
          f => `${f.tableAlias || f.tableCode}.${f.fieldCode}`,
        );
        let returnValue = _.transform(
          fasDynamicFilter,
          (r, val, key) => {
            const field = mapKey[key];
            if (field) {
              r[field.fieldAlias] = val;
            } else {
              r[_.last(key.split('.'))] = val;
            }
          },
          {},
        );
        return returnValue;
      },
      getFasDynamicGroupByFilter(advancedFilter) {
        return publicMethod.getSummaryFilter(advancedFilter);
      },
      getSummaryFilter(advancedFilter) {
        if (typeof advancedFilter === 'string') {
          try {
            advancedFilter = JSON.parse(advancedFilter);
          } catch (error) {
            console.warn('QuickFilter.getQuickFilter', error);
          }
        }
        return publicMethod.zipFasDynamicFilter({}, advancedFilter?.Filters);
      },
      getSummaryFields() {
        let groupFields = [];
        let { ExtSetting } = publicMethod.getGroupColumnStatement();
        if (ExtSetting && ExtSetting.GroupColumns) {
          groupFields = _.map(ExtSetting.GroupColumns, item =>
            _.last(item.Code.split('.')),
          );
        }
        return groupFields.join();
      },
      setTagMode() {
        mappingExpose.displayMode.value = 'tag';
      },
      setReactiveMode() {
        mappingExpose.displayMode.value = 'reactive';
      },
      toggleDisplayMode() {
        mappingExpose.displayMode.value == 'reactive'
          ? publicMethod.setTagMode()
          : publicMethod.setReactiveMode();
      },
      computedFilterItems,
      setSelectedItem(obj, opts = { clear: false, forceClear: false }) {
        if (opts.clear && Object.keys(obj).length === 0) {
          publicMethod.clearSelected();
          return;
        }
        if (opts.forceClear) {
          publicMethod.clearSelected();
        }
        // debugger;
        _.each(obj, (val, key) => {
          let item = _.find(computedFilterItems.value, f => {
            return (
              f.fieldAlias === key ||
              `${f.tableAlias || f.tableCode}.${f.fieldCode}` === key
            );
          });
          if (item) {
            switch (item.valueType) {
              case FilterFieldValueRange.Date:
                debugger;
                let dataValue = val;
                if (_.isArray(val)) {
                  dataValue = getDateRange2Value(val)?.value;
                } else {
                  if (_.startsWith(val, '@')) {
                    /** [@today|@yesterday|@week|@last_week|@month|@last_month|@year|@last_year] */
                    dataValue = val;
                  } else {
                    dataValue = getDateRange2Value([val, val])?.value;
                  }
                }
                item.valueRange = [
                  {
                    selected: false,
                    label: '',
                    value: dataValue,
                    _isSetValueFlag: true,
                  },
                ];
                break;
              case FilterFieldValueRange.Boolean:
                if (item && item.valueRange) {
                  _.each(item.valueRange, eachItem => {
                    switch (val) {
                      case 'true':
                      case 'True':
                      case 'TRUE':
                        eachItem.selected = eachItem.value == true;
                        break;
                      case 'false':
                      case 'False':
                      case 'FALSE':
                        eachItem.selected = eachItem.value == false;
                        break;
                      case '':
                      case null:
                        eachItem.selected = false;
                        break;
                      default:
                        eachItem.selected = eachItem.value == Boolean(+val);
                        break;
                    }
                  });
                }
                break;
              default:
                if (FilterFieldDisplayType.SelectHelper === item.displayType) {
                  if (val === null) {
                    /** 下拉帮助类型如何值为null，忽略避免错误的构造选择项 */
                    item.valueRange = [{ selected: false }];
                    cacheSelectHelperValue(item.ID, []);
                    return;
                  }
                  switch (item.valueType) {
                    case FilterFieldValueRange.SDO:
                      if (item) {
                        if (item.isMultiple) {
                          let valArray;
                          if (_.isArray(val)) {
                            valArray = val;
                          } else {
                            if (isValueDestructuring(val)) {
                              /** 高级对象模式 */
                              let { value, label } = valueDestructuring(val);
                              if (_.isNil(value)) {
                                value = '';
                              }
                              let valueArray = (`${value}` || '').split?.(',');
                              let labelArray = (label || '').split?.(',');
                              if (valueArray) {
                                /** 多选多值 */
                                valArray = valueArray.map((v, i) => {
                                  return valueStructuring({
                                    Value: v,
                                    ValueName: labelArray[i],
                                  });
                                });
                              } else {
                                /** 多选单值 */
                                valArray = [val];
                              }
                            } else {
                              if (_.isNumber(val)) {
                                valArray = [val];
                              } else {
                                /** 普通值 */
                                if (_.isNil(val)) {
                                  val = '';
                                }
                                valArray = (val || '').split?.(',');
                              }
                            }
                          }

                          if (valArray) {
                            item.valueRange = valArray.map(o => ({
                              selected: true,
                              ...valueDestructuring(o),
                            }));
                          } else {
                            item.valueRange = [
                              {
                                selected: true,
                                ...valueDestructuring(val),
                              },
                            ];
                          }
                        } else {
                          item.valueRange = [
                            {
                              selected: true,
                              ...valueDestructuring(val),
                            },
                          ];
                        }
                      }
                      break;
                  }
                  cacheSelectHelperValue(item.ID, item.valueRange);
                } else {
                  if (item && item.valueRange) {
                    if (item.isMultiple) {
                      _.each(item.valueRange, eachItem => {
                        eachItem.selected = false;
                      });
                      let valArray;
                      if (_.isArray(val)) {
                        valArray = val;
                      } else {
                        if (isValueDestructuring(val)) {
                          /** 高级对象模式 */
                          let { value, label } = valueDestructuring(val);
                          if (_.isNil(value)) {
                            value = '';
                          }
                          let valueArray = (`${value}` || '').split?.(',');
                          let labelArray = (label || '').split?.(',');
                          if (valueArray) {
                            /** 多选多值 */
                            valArray = valueArray.map((v, i) => {
                              return valueStructuring({
                                Value: v,
                                ValueName: labelArray[i],
                              });
                            });
                          } else {
                            /** 多选单值 */
                            valArray = [val];
                          }
                        } else {
                          if (_.isNumber(val)) {
                            valArray = [val];
                          } else {
                            /** 普通值 */
                            if (_.isNil(val)) {
                              val = '';
                            }
                            valArray = (val || '').split?.(',');
                          }
                        }
                      }
                      // let valArray = _.isArray(val) ? setSelectval : [val];
                      _.each(valArray, eachVal => {
                        let eachItem = _.find(item.valueRange, f => {
                          return '' === eachVal
                            ? f.value === eachVal
                            : f.value == eachVal;
                        });
                        if (eachItem) {
                          eachItem.selected = true;
                        }
                      });
                    } else {
                      _.each(item.valueRange, eachItem => {
                        eachItem.selected =
                          '' === val
                            ? eachItem.value === val
                            : eachItem.value == val;
                      });
                    }
                  }
                }
                break;
            }
          }
        });
      },
      updateByFilter(w, opts) {
        if (_.isNil(w)) return;
        if (false !== opts?.isClearSelected) {
          publicMethod.clearSelected();
        }
        if (
          w.isComplex &&
          false === w.isComplex() &&
          (w.getAllFilters ||
            (w.filterExpression && typeof w.filterExpression == 'string'))
        ) {
          let filterExpression =
            (w.getAllFilters && w.getAllFilters()) || w.filterExpression;
          let mapKey = _.keyBy(
            props.filterFields,
            f => `${f.tableAlias || f.tableCode}.${f.fieldCode}`,
          );
          let fObj = JSON.parse(filterExpression);
          if (fObj.Filters && fObj.Filters.length > 0) {
            let filter = _.transform(
              fObj.Filters,
              (r, f) => {
                const cFilterField = mapKey[f.Code];

                if (cFilterField) {
                  if (f.ElementType == 'Filter') {
                    switch (f.Condition) {
                      case '=':
                        if (
                          f.DataType == 'Date' &&
                          typeof f.Value == 'string'
                        ) {
                          let dayValue = dayjs(f.Value);
                          r[cFilterField.fieldAlias] = [
                            dayValue.startOf('day').format(),
                            dayValue.endOf('day').format(),
                          ];
                        } else {
                          r[cFilterField.fieldAlias] = f.Value;
                        }
                        break;
                      case 'in':
                        if (cFilterField.isMultiple) {
                          let fValue = _.isNil(f.Value) ? '' : `${f.Value}`;
                          r[cFilterField.fieldAlias] = fValue.split(',');
                        } else {
                          r[cFilterField.fieldAlias] = null;
                        }
                        break;
                      case 'between':
                        if (f.DataType == 'Date' && f.Value.length == 2) {
                          r[cFilterField.fieldAlias] = [
                            dayjs(f.Value[0]).startOf('day').format(),
                            dayjs(f.Value[1]).endOf('day').format(),
                          ];
                        } else {
                          r[cFilterField.fieldAlias] = f.Value;
                        }
                        break;
                      default:
                        r[cFilterField.fieldAlias] = null;
                        break;
                    }
                  }

                  if (
                    FilterFieldDisplayType.SelectHelper ===
                    cFilterField.displayType
                  ) {
                    debugger;
                    if (null !== f.Value) {
                      r[cFilterField.fieldAlias] = valueStructuring(f);
                    } else {
                      r[cFilterField.fieldAlias] = null;
                    }
                  }
                }
              },
              {},
            );
            syncFilter = filter;
            publicMethod.setSelectedItem(filter);
          }
        } else {
          publicMethod.setSelectedItem(w);
        }
      },
      getAllFilters(filters) {
        let mapKey = _.map(
          props.filterFields,
          f => `${f.tableAlias || f.tableCode}.${f.fieldCode}`,
        );
        let mapping = _.mapKeys(
          computedFilterItems.value,
          f => `${f.tableAlias || f.tableCode}.${f.fieldCode}`,
        );
        function genEmptyFilterItem(code) {
          let DataType = {};
          switch (mapping[code].valueType) {
            case FilterFieldValueRange.Date:
              DataType.DataType = 'DateTime';
              break;
            case FilterFieldValueRange.Boolean:
              DataType.DataType = 'Boolean';
              break;
          }
          return {
            Code: code,
            Condition: '=',
            ElementType: 'Filter',
            Name: mapping[code].fieldName,
            ...DataType,
            Value: null,
            ValueName: null,
          };
        }
        let filter = publicMethod.getQuickFilter(filters);
        if (filter) {
          let l = _.transform(
            filter.Filters,
            (r, f) => {
              if ('Filter' === f.ElementType) {
                r.push(f.Code);
              }
            },
            [],
          );
          _.xor(mapKey, l).forEach(code => {
            filter.Filters.push(
              { ElementType: 'Relation', Relation: 'and' },
              genEmptyFilterItem(code),
            );
          });
        } else {
          filter = {
            ElementType: 'Group',
            Filters: _.transform(
              mapKey,
              (r, code, i) => {
                r.push(genEmptyFilterItem(code));
                if (i < mapKey.length - 1) {
                  r.push({
                    ElementType: 'Relation',
                    Relation: 'and',
                  });
                }
              },
              [],
            ),
          };
        }

        return filter == null ? null : JSON.stringify(filter);
      },
      isEnableStatistics: computed(() => {
        return _.some(mappingProps.filterFields, f => f.enableStatistics);
      }),
      initEnableStatistics: _.some(props.filterFields, f => f.enableStatistics),
      initEnableStatisticsItems: _.filter(
        props.filterFields,
        f => f.enableStatistics,
      ).map(f => f.fieldCode),
      toggleStatistics(autoQuery = true) {
        let enable = !publicMethod.isEnableStatistics.value;
        publicMethod.changeStatistics({ enable, autoQuery });
      },
      changeStatistics({ enable = true, autoQuery = true }) {
        let changedValue = {};
        forIn(mappingProps.filterFields, eachItem => {
          if (
            FilterFieldDisplayType.SelectHelper !== eachItem.displayType &&
            publicMethod.initEnableStatisticsItems.includes(eachItem.fieldCode)
          ) {
            eachItem.enableStatistics = enable;
            changedValue[eachItem.fieldCode] = enable;
          }
        });
        if (enable && autoQuery) {
          publicMethod.querySummary();
        }
        return changedValue;
      },
      setHelpTip(opts, val = '') {
        return setHelpTipBase(mappingProps?.filterFields, opts, val);
      },
    };

    let syncFilter;
    watch(
      () => props.quickItems,
      (newValue, oldValue) => {
        publicMethod.updateByFilter(syncFilter);
        emit('quickItemsChanged', { newValue, oldValue });
      },
      {
        once: true,
      },
    );

    // const initEnableStatisticsItems = [];
    // const unWatch = watch(
    //   () => props.filterFields,
    //   (newVal, oldVal) => {
    //     debugger;
    //     initEnableStatisticsItems = _.filter(
    //       newVal,
    //       f => f.enableStatistics,
    //     ).map(f => f.fieldCode);
    //     unWatch();
    //   },
    //   { immediate: true },
    // );


    const [mappingProps, mappingExpose] = useMappingProps(props, {
      ...twoWayProps,
      ...publicMethod,
    });

    expose(mappingExpose);

    onMounted(() => {
      emit('init', refRoot.value);
      if (mappingProps.initQuerySummary) {
        emitQuerySummary();
      }
    });

    const computedDisplayModeWithTag = computed(() => {
      return mappingExpose.displayMode.value == 'tag';
    });

    const isDesktop = computed(() => {
      return !($q.screen.xs || $q.platform.is.mobile);
    });
    function cacheSelectHelperValue(key, value = void 0) {
      const cache = `_q_${key}`;
      if (value !== void 0) {
        refRoot.value[cache] = value;
      }
      return refRoot.value[cache];
    }

    function readerMock() {
      return (
        <div
          class='row items-center FilterItem-Desktop'
          style='position: relative;'
        >
          <div class='row FilterItem items-center'>
            <div class='t-quick-filter_chip-group-label'>示例效果</div>
            <div
              class='q-chip row inline no-wrap items-center bg- q-chip--dense q-chip--selected q-chip--clickable cursor-pointer non-selectable q-hoverable q-chip--square t-chip tr-chip-select-type-moon tr-chip-select-type-moon'
              tabindex='1'
              visible='true'
              checksize='15px'
              style='/*height: 24px;*/ --check-size: 15px; --fb515dcc: 15px;'
            >
              <div class='q-focus-helper' />
              <i
                class='q-icon notranslate material-icons q-chip__icon q-chip__icon--left'
                aria-hidden='true'
                role='presentation'
              >
                check
              </i>
              <div class='q-chip__content col row no-wrap items-center q-anchor--skip'>
                模拟项1 <span class='item-count'>100</span>
              </div>
            </div>
            <div
              class='q-chip row inline no-wrap items-center bg- q-chip--dense q-chip--clickable cursor-pointer non-selectable q-hoverable q-chip--square t-chip tr-chip-select-type-moon tr-chip-select-type-moon'
              tabindex='1'
              visible='true'
              checksize='15px'
              style='/*height: 24px;*/ --check-size: 15px; --fb515dcc: 15px;'
            >
              <div class='q-focus-helper' />
              <div class='q-chip__content col row no-wrap items-center q-anchor--skip'>
                模拟项2 <span class='item-count'>0</span>
              </div>
            </div>
            <div
              class='q-chip row inline no-wrap items-center bg- q-chip--dense q-chip--clickable cursor-pointer non-selectable q-hoverable q-chip--square t-chip tr-chip-select-type-moon tr-chip-select-type-moon'
              tabindex='1'
              visible='true'
              checksize='15px'
              style='/*height: 24px;*/ --check-size: 15px; --fb515dcc: 15px;'
            >
              <div class='q-focus-helper' />
              <div class='q-chip__content col row no-wrap items-center q-anchor--skip'>
                模拟项3 <span class='item-count'>50</span>
              </div>
            </div>
          </div>
        </div>
      );
    }

    return () => {
      return (
        <div
          v-removeTabindex
          ref={refRoot}
          class={[
            't-quick-filter',
            false == isDesktop.value &&
              computedDisplayModeWithTag.value &&
              't-tag-mode-mobile',
          ]}
          v-show={mappingProps.visible}
        >
          {false && (
            <div>
              <fieldset>
                <legend>quickItemSummary</legend>
                {JSON.stringify(props.quickItemSummary)}
              </fieldset>
              <fieldset>
                <legend>computedQuickItemSummary</legend>
                {JSON.stringify(props.computedQuickItemSummary)}
              </fieldset>
              <fieldset style={{ height: '100px', overflow: 'auto' }}>
                <legend>computedFilterItems</legend>
                {JSON.stringify(computedFilterItems.value)}
              </fieldset>
              <fieldset style={{ height: '100px', overflow: 'auto' }}>
                <legend>computedFilterStatement</legend>
                {JSON.stringify(computedFilterStatement.value)}
              </fieldset>
            </div>
          )}
          {/**
           *
           * 这里不可以删除否则计算属性不能更新 */}
          <fieldset
            v-show={false}
            style={{ height: '100px', overflow: 'auto' }}
          >
            <legend>
              computedFilterStatement(这里不可以删除否则计算属性不能更新){' '}
            </legend>
            {JSON.stringify(computedFilterStatement.value)}
            {JSON.stringify(computedFilterFields.value)}
            {JSON.stringify(computedFilterItems.value)}
            {/* {JSON.stringify(computedGroupColumnStatement.value)} */}
          </fieldset>
          {/* 这里不可以删除否则计算属性不能更新 */}
          {inDesign.value &&
            computedFilterItems.value.length == 0 &&
            readerMock()}
          {isDesktop.value || computedDisplayModeWithTag.value ? (
            <Desktop
              loading={props.loading}
              onFilterChanged={emitFilterChanged}
              showTotalCount={mappingProps.showTotalCount}
              showSummaryCount={mappingProps.showSummaryCount}
              filterItems={computedDisplayFilterItems.value}
              selectHelperSearchConfig={mappingProps.selectHelperSearchConfig}
              selectHelperUpdateValueRange={(args, valueRange) => {
                let item = _.find(computedFilterItems.value, { ID: args.ID });
                cacheSelectHelperValue(args.ID, valueRange);
                refRoot.value.data;
                item && (item.valueRange = valueRange);
              }}
            >
              {{
                before: slots.before,
                after: slots.after,
              }}
            </Desktop>
          ) : (
            <>
              {false == props.isPcOnly && (
                <Mobile
                  loading={props.loading}
                  showTotalCount={mappingProps.showTotalCount}
                  showSummaryCount={mappingProps.showSummaryCount}
                  onFilterChanged={emitFilterChanged}
                  onSearchValue={emitSearchValue}
                  onLoadMore={payload => {
                    emit('loadMore', payload);
                  }}
                  filterItems={computedFilterItems.value}
                  selectHelperSearchConfig={
                    mappingProps.selectHelperSearchConfig
                  }
                  selectHelperUpdateValueRange={(args, valueRange) => {
                    let item = _.find(computedFilterItems.value, {
                      ID: args.ID,
                    });
                    cacheSelectHelperValue(args.ID, valueRange);
                    refRoot.value.data;
                    item && (item.valueRange = valueRange);
                  }}
                  optionsPosition={mappingProps.optionsPosition}
                >
                  {{
                    before: slots.before,
                    after: slots.after,
                  }}
                </Mobile>
              )}
            </>
          )}
        </div>
      );
    };
  },
});
